/*   Copyright (C) 2008  Jeroen v. Schagen & Youri Lima
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

using System;

using Engine.Core;
using Engine.Math;
using Engine.Rendering.Library;

namespace Engine.Rendering
{
    public class Camera : Component
    {
        private Frustum frustum;

        # region Constructor

        public Camera(String name) : base(name)
        {
            frustum = new Frustum(this, (float) System.Math.PI / 4, 1.33f, 1f, 500f);

            // Attach event handler
            DataModified += new ComponentEventHandler(Update);
        }

        # endregion


        # region Function

        private void Update(object sender)
        {
            // Rebuild frustum planes
            frustum.Build();
        }

        public void Display(Microsoft.DirectX.Direct3D.Device device, int width, int height)
        {
            // Calculate ratio
            float ratio = width / height;

            // Update frustum when needed
            if (ratio != frustum.Ratio) frustum.Ratio = ratio;

            // Transform device
            device.Transform.Projection = Microsoft.DirectX.Matrix.PerspectiveFovLH(frustum.Angle, frustum.Ratio, frustum.Near, frustum.Far);
            device.Transform.View = DirectX.ToDirectX(((Matrix4) GetAdapter(typeof(Matrix4))).Inverse);
        }

        public bool Visible(Model obj)
        {
            // Check visibility
            return frustum.InFrustum(obj.WorldPosition);
        }

        # endregion


        # region Accessor

        public Frustum Frustum
        {
            get { return frustum; }
        }

        # endregion

        public override string ToString()
        {
            return base.ToString();
        }
    }
}
